/***************************************************************************
 *                                                                         *
 * Copyright (c) 2007 - 2009 Nuvoton Technology Corp. All rights reserved.*
 *                                                                         *
 ***************************************************************************/
 

#ifdef ECOS
#include "stdio.h"
#include "string.h"
#include "stdlib.h"
#include "drv_api.h"
#include "diag.h"
#include "wbio.h"
#include "NUC900_GE.h"
#include "NUC900_reg.h"
#else
#include <stdio.h>
#include "NUC900_GE.h"
#include "wbio.h"
#ifdef _NUC900_
#include "NUC900_reg.h"
#else
#include "reg702.h"
#endif
#endif


///////////////////////////////////////////////////////////////////////////////
//
// Function: screen_sprite_blt()
//
// Description:
//   OffScreen-to-OnScreen SpriteBlt with SRCCOPY. 
//   The sprite always starts from (0,0) for the BLT.
//
///////////////////////////////////////////////////////////////////////////////
void screen_sprite_blt(int destx, int desty, int sprite_width, int sprite_height, void *buf)
{
  UINT32 cmd32, pitch, dest_start, src_start, dimension;
  UINT32 data32, alpha;

#ifdef DEBUG 
  printf("screen_sprite_blt():\n");
  printf("x=%d y=%d width=%d height=%d\n", destx, desty, sprite_width, sprite_height);
#endif 
 
  cmd32 = 0xcc430000;
  #if 0
  cmd32 = 0xcc430010; // test hardware PDT bug
  #endif
   
  outpw(REG_2D_GEC, cmd32);
  
  pitch = GFX_WIDTH << 16 | sprite_width; // pitch in pixel
  outpw(REG_2D_GESDP, pitch);

  src_start = 0; // start from (0,0) of sprite
  outpw(REG_2D_GESSXYL, src_start);
  
  dest_start = desty << 16 | destx;
  outpw(REG_2D_GEDSXYL, dest_start);
  
  dimension = sprite_height << 16 | sprite_width;
  outpw(REG_2D_GEDIXYL, dimension);  
  
  outpw(REG_2D_GEXYSORG, (UINT32)buf);
  outpw(REG_2D_GEXYDORG, (int)GFX_START_ADDR);  //smf
  
  if (_ClipEnable)
  {
    cmd32 |= 0x00000200;
    if (_OutsideClip)
    {
      cmd32 |= 0x00000100;
    }
    outpw(REG_2D_GEC, cmd32);
    outpw(REG_2D_GECBTL, _ClipTL);
    outpw(REG_2D_GECBBR, _ClipBR);
  }  

#if 1
  
  //
  // default source color transparent is ON
  //
  
  cmd32 |= 0x00008000; // color transparency 
  outpw(REG_2D_GEC, cmd32);
  outpw(REG_2D_GETC, make_color(COLOR_KEY));
  outpw(REG_2D_GETCM, 0xffffff);
  
#else

  if (_DrawMode==MODE_TRANSPARENT)
  {
    cmd32 |= 0x00008000; // color transparency 
    outpw(REG_2D_GEC, cmd32);
    outpw(REG_2D_GETC, _ColorKey);
    outpw(REG_2D_GETCM, _ColorKeyMask);
  }  
  else if (_DrawMode==MODE_DEST_TRANSPARENT)
  {
    cmd32 |= 0x00009000;
    outpw(REG_2D_GEC, cmd32);
    outpw(REG_2D_GETC, _ColorKey);
    outpw(REG_2D_GETCM, _ColorKeyMask);
  }

#endif
  
  if (_EnableAlpha)
  {
    cmd32 |= 0x00200000;
    outpw(REG_2D_GEC, cmd32);
    
    data32 = inpw(REG_2D_GEMC) & 0x0000ffff;
    alpha = (UINT32)((_AlphaKs << 8) | _AlphaKd);
    data32 |= (alpha << 16);
    
    outpw(REG_2D_GEMC, data32);
  }
  
  outpw(REG_2D_GEC, cmd32);

  outpw(REG_2D_GETG, 1); 
  
  while ((inpw(REG_2D_GEINTS)&0x01)==0); // wait for command complete  
  
  outpw(REG_2D_GEINTS, 1); // clear interrupt status
}


///////////////////////////////////////////////////////////////////////////////
//
// Function: screen_sprite_bltx()
//
// Description:
//   OffScreen-to-OnScreen SpriteBlt with SRCCOPY. 
//   The sprite starting address can be programmed. 
//
///////////////////////////////////////////////////////////////////////////////
void screen_sprite_bltx(int x, int y, int sprite_sx, int sprite_sy, int width, int height, int sprite_width, int sprite_height, void *buf)
{
  UINT32 cmd32, pitch, dest_start, src_start, dimension;
  UINT32 data32, alpha;

#ifdef DEBUG 
  printf("screen_sprite_bltx(): (%d,%d)\n", x, y);
  printf("sprite width=%d height=%d\n", sprite_width, sprite_height);
  printf("x=%d y=%d width=%d height=%d\n", sprite_sx, sprite_sy, width, height);
#endif 
 
  cmd32 = 0xcc430000;
   
  outpw(REG_2D_GEC, cmd32);
  
  pitch = GFX_WIDTH << 16 | sprite_width; // pitch in pixel
  outpw(REG_2D_GESDP, pitch);

  outpw(REG_2D_GEXYSORG, (UINT32)buf);
  outpw(REG_2D_GEXYDORG, (int)GFX_START_ADDR);  //smf
  
  src_start = sprite_sy << 16 | sprite_sx;
  outpw(REG_2D_GESSXYL, src_start);
  
  dest_start = y << 16 | x;
  outpw(REG_2D_GEDSXYL, dest_start);
  
  dimension = height << 16 | width;
  outpw(REG_2D_GEDIXYL, dimension);  
  
  if (_ClipEnable)
  {
    cmd32 |= 0x00000200;
    if (_OutsideClip)
    {
      cmd32 |= 0x00000100;
    }
    outpw(REG_2D_GEC, cmd32);
    outpw(REG_2D_GECBTL, _ClipTL);
    outpw(REG_2D_GECBBR, _ClipBR);
  }  

#if 1
  
  //
  // default source color transparent is ON
  //
  cmd32 |= 0x00008000; // color transparency 
  outpw(REG_2D_GEC, cmd32);
  outpw(REG_2D_GETC, make_color(COLOR_KEY));
  outpw(REG_2D_GETCM, 0xffffff);

#else

  if (_DrawMode==MODE_TRANSPARENT)
  {
    cmd32 |= 0x00008000; // color transparency 
    outpw(REG_2D_GEC, cmd32);
    outpw(REG_2D_GETC, _ColorKey);
    outpw(REG_2D_GETCM, _ColorKeyMask);
  }  
  else if (_DrawMode==MODE_DEST_TRANSPARENT)
  {
    cmd32 |= 0x00009000;
    outpw(REG_2D_GEC, cmd32);
    outpw(REG_2D_GETC, _ColorKey);
    outpw(REG_2D_GETCM, _ColorKeyMask);
  }

#endif
  
  if (_EnableAlpha)
  {
    cmd32 |= 0x00200000;
    outpw(REG_2D_GEC, cmd32);
    
    data32 = inpw(REG_2D_GEMC) & 0x0000ffff;
    alpha = (UINT32)((_AlphaKs << 8) | _AlphaKd);
    data32 |= (alpha << 16);
    
    outpw(REG_2D_GEMC, data32);
  }
  
  outpw(REG_2D_GETG, 1); 
  
  while ((inpw(REG_2D_GEINTS)&0x01)==0); // wait for command complete  
  
  outpw(REG_2D_GEINTS, 1); // clear interrupt status
}


///////////////////////////////////////////////////////////////////////////////
//
// Function: screen_sprite_rop_blt()
//
// Description:
//   OffScreen-to-OnScreen SpriteBlt with ROP. 
//   The sprite always starts from (0,0) for the BLT.
//
///////////////////////////////////////////////////////////////////////////////
void screen_sprite_rop_blt(int x, int y, int sprite_width, int sprite_height, void *buf, int rop)
{
  UINT32 cmd32, pitch, dest_start, src_start, dimension;
  UINT32 data32, alpha;

#ifdef DEBUG 
  printf("screen_sprite_rop_blt():\n");
  printf("x=%d y=%d width=%d height=%d\n", x, y, sprite_width, sprite_height);
  printf("rop=0x%x\n", rop);
#endif  

  cmd32 = 0x00430000 | (rop << 24);

  if (_PatternType==TYPE_MONO)
  {
    cmd32 |= 0x00000010; // default is TYPE_COLOR
  }
   
  outpw(REG_2D_GEC, cmd32);
  
  pitch = GFX_WIDTH << 16 | sprite_width; // pitch in pixel
  outpw(REG_2D_GESDP, pitch);

  src_start = 0; // start from (0,0) of sprite
  outpw(REG_2D_GESSXYL, src_start);
  
  dest_start = y << 16 | x;
  outpw(REG_2D_GEDSXYL, dest_start);
  
  dimension = sprite_height << 16 | sprite_width;
  outpw(REG_2D_GEDIXYL, dimension);  
  
  outpw(REG_2D_GEXYSORG, (UINT32)buf);
  outpw(REG_2D_GEXYDORG,(int) GFX_START_ADDR);  //smf 
 
  if (_ClipEnable)
  {
    cmd32 |= 0x00000200;
    if (_OutsideClip)
    {
      cmd32 |= 0x00000100;
    }
    outpw(REG_2D_GEC, cmd32);
    outpw(REG_2D_GECBTL, _ClipTL);
    outpw(REG_2D_GECBBR, _ClipBR);
  }  

#if 1
  
  //
  // default source color transparent is ON
  //
  cmd32 |= 0x00008000; // color transparency 
  outpw(REG_2D_GEC, cmd32);
  outpw(REG_2D_GETC, make_color(COLOR_KEY));
  outpw(REG_2D_GETCM, 0xffffff);
  
#else

  if (_DrawMode==MODE_TRANSPARENT)
  {
    cmd32 |= 0x00008000; // color transparency 
    outpw(REG_2D_GEC, cmd32);
    outpw(REG_2D_GETC, _ColorKey);
    outpw(REG_2D_GETCM, _ColorKeyMask);
  }  
  else if (_DrawMode==MODE_DEST_TRANSPARENT)
  {
    cmd32 |= 0x00009000;
    outpw(REG_2D_GEC, cmd32);
    outpw(REG_2D_GETC, _ColorKey);
    outpw(REG_2D_GETCM, _ColorKeyMask);
  }

#endif
  
  if (_EnableAlpha)
  {
    cmd32 |= 0x00200000;
    outpw(REG_2D_GEC, cmd32);
    
    data32 = inpw(REG_2D_GEMC) & 0x0000ffff;
    alpha = (UINT32)((_AlphaKs << 8) | _AlphaKd);
    data32 |= (alpha << 16);
    
    outpw(REG_2D_GEMC, data32);
  }

  // 
  // Hardware may halt in ROP=0x00 and 0xFF.
  // This bug must be avoided by hardware by setting
  // b15 = 1
  // b14 = 0
  // b12 = 1
  //
  if ((rop==0x00) || (rop==0xff))   // blackness & whiteness, smf
  {
    cmd32 = (cmd32 & 0xffff0fff) | 0x00009000;
    outpw(REG_2D_GEC, cmd32);
  }
  
  outpw(REG_2D_GETG, 1); 
  
  while ((inpw(REG_2D_GEINTS)&0x01)==0); // wait for command complete  
  
  outpw(REG_2D_GEINTS, 1); // clear interrupt status
}


///////////////////////////////////////////////////////////////////////////////
//
// Function: screen_sprite_rop_blt()
//
// Description:
//   OffScreen-to-OnScreen SpriteBlt with ROP. 
//   The sprite always starts from (0,0) for the BLT.
//
///////////////////////////////////////////////////////////////////////////////
void screen_sprite_rop_bltx(int x, int y, int sprite_sx, int sprite_sy, int width, int height, int sprite_width, int sprite_height, void *buf, int rop)
{
  UINT32 cmd32, pitch, dest_start, src_start, dimension;
  UINT32 data32, alpha;

#ifdef DEBUG 
  printf("screen_sprite_rop_bltx():\n");
  printf("x=%d y=%d width=%d height=%d\n", x, y, sprite_width, sprite_height);
  printf("rop=0x%x\n", rop);
#endif  

  cmd32 = 0x00430000 | (rop << 24);

  if (_PatternType==TYPE_MONO)
  {
    cmd32 |= 0x00000010; // default is TYPE_COLOR
  }
   
  outpw(REG_2D_GEC, cmd32);

  pitch = GFX_WIDTH << 16 | sprite_width; // pitch in pixel
  outpw(REG_2D_GESDP, pitch);

  src_start = sprite_sy << 16 | sprite_sx;
  outpw(REG_2D_GESSXYL, src_start);
  
  dest_start = y << 16 | x;
  outpw(REG_2D_GEDSXYL, dest_start);
  
  dimension = height << 16 | width;
  outpw(REG_2D_GEDIXYL, dimension);  
  
  outpw(REG_2D_GEXYSORG, (UINT32)buf);
  outpw(REG_2D_GEXYDORG, (int)GFX_START_ADDR);  //smf
  
  if (_ClipEnable)
  {
    cmd32 |= 0x00000200;
    if (_OutsideClip)
    {
      cmd32 |= 0x00000100;
    }
    outpw(REG_2D_GEC, cmd32);
    outpw(REG_2D_GECBTL, _ClipTL);
    outpw(REG_2D_GECBBR, _ClipBR);
  }  

#if 1
  
  //
  // default source color transparent is ON
  //
  cmd32 |= 0x00008000; // color transparency 
  outpw(REG_2D_GEC, cmd32);
  outpw(REG_2D_GETC, make_color(COLOR_KEY));
  outpw(REG_2D_GETCM, 0xffffff);

#else

  if (_DrawMode==MODE_TRANSPARENT)
  {
    cmd32 |= 0x00008000; // color transparency 
    outpw(REG_2D_GEC, cmd32);
    outpw(REG_2D_GETC, _ColorKey);
    outpw(REG_2D_GETCM, _ColorKeyMask);
  }  
  else if (_DrawMode==MODE_DEST_TRANSPARENT)
  {
    cmd32 |= 0x00009000;
    outpw(REG_2D_GEC, cmd32);
    outpw(REG_2D_GETC, _ColorKey);
    outpw(REG_2D_GETCM, _ColorKeyMask);
  }

#endif
  
  if (_EnableAlpha)
  {
    cmd32 |= 0x00200000;
    outpw(REG_2D_GEC, cmd32);
    
    data32 = inpw(REG_2D_GEMC) & 0x0000ffff;
    alpha = (UINT32)((_AlphaKs << 8) | _AlphaKd);
    data32 |= (alpha << 16);
    
    outpw(REG_2D_GEMC, data32);
  }
   
  // 
  // Hardware may halt in ROP=0x00 and 0xFF.
  // This bug must be avoided by hardware by setting
  // b15 = 1
  // b14 = 0
  // b12 = 1
  //
  if ((rop==0x00) || (rop==0xff))
  {
    cmd32 = (cmd32 & 0xffff0fff) | 0x00009000;
    outpw(REG_2D_GEC, cmd32);
  }

  outpw(REG_2D_GETG, 1); 
  
  while ((inpw(REG_2D_GEINTS)&0x01)==0); // wait for command complete  
  
  outpw(REG_2D_GEINTS, 1); // clear interrupt status
}
